# -*- coding: utf-8 -*-

#    OriginDB
#    Copyright (C) 2009  Jason Power <power.jg@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from dbobject import DBObject
from chemdb import dbHandle

class Fingerprint(DBObject):

	def __init__(self, fingerprintId=-1, fpstr=""):

		DBObject.__init__(self)

		self.id = fingerprintId

		#string of fingerprint
		self._things['fpstr'] = fpstr

	def _getItem(self, name):
		if name=='fpstr':
			fpstr = dbHandle.get('fingerprint', 'compound_fp', 'id', self.id)
			self._things['fpstr'] = fpstr
			return fpstr

	def insert(self, cid):
		if self.id != -1:
			raise AttributeError, "Object already in DB"

		self.id = dbHandle.insertFingerprint(cid)

		for i in self._needToUpdate:
			self.updateDB(i)
		self._needToUpdate = []

	def updateDB(self, name):
		if self.id == -1:
			self._needToUpdate.append(name)
			return

		if name in 'fpstr':
			dbHandle.updateFingerprint(self.id, 'fingerprint', self._things['fpstr'])
		else:
			raise NameError, name

	def setPybelFp(self, fp):
		"""fp is the pybel fingerprint object"""

		fpstr = ''
		for i in fp.bits:
			fpstr += str(i)+','

		print "setting fp to", fpstr
		self.fpstr = fpstr

	def __and__(self, other):
		"""Basically this is just an intersection of the two
		   fpstr's
		"""
		if (type(other) != Fingerprint):
			raise TypeError, "Can only do an & on other Fingerprints"

		l1 = [int(i) for i in self.fpstr.split(',')[0:-1]]
		l2 = [int(i) for i in other.fpstr.split(',')[0:-1]]

		#intersection is faster with dicts than lists ;)
		int_dict = {}
		l1_dict = {}
		for e in l1:
			l1_dict[e] = 1
		for e in l2:
			if list1_dict.has_key(e):
				int_dict[e] = 1
		return int_dict.keys()

	def __or__(self, other):
		"""Basically this is just an union of the two
		   fpstr's
		"""
		if (type(other) != Fingerprint):
			raise TypeError, "Can only do an & on other Fingerprints"

		l1 = [int(i) for i in self.fpstr.split(',')[0:-1]]
		l2 = [int(i) for i in other.fpstr.split(',')[0:-1]]

		#intersection is faster with dicts than lists ;)
		union_dict = {}
		for e in l1:
			union_dict[e] = 1
		for e in l2:
			union_dict[e] = 1
		return union_dict.keys()


	#the tanimoto coef is defined by:
    #Number of bits set in (patternFP & targetFP) /
    #Number of bits in (patternFP | targetFP)
    #this is going to be very very slow
    #maybe think of a better way, maybe not.S
	def tanimoto(self, other):
		"""coeficient of how similar two molecules are
		"""

		return float(len(self & other))/len(self | other)